package xin.alum.aim.rabbitmq;


import com.fasterxml.jackson.core.type.TypeReference;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.beans.factory.annotation.Autowired;
import xin.alum.aim.AIM;
import xin.alum.aim.constant.Constants;
import xin.alum.aim.groups.Session;
import xin.alum.aim.groups.SessionGroups;
import xin.alum.aim.groups.Sessions;
import xin.alum.aim.model.Pusher;
import xin.alum.aim.model.Reply;
import xin.alum.aim.util.JSONUtils;


class RabbitMessageListener implements ChannelAwareMessageListener {

    @Autowired
    Sessions sessions;

    @Autowired
    SessionGroups groups;

    @Override
    public void onMessage(Message message, Channel channel) {
        Pusher pusher;
        switch (message.getMessageProperties().getReceivedRoutingKey()) {
            case Constants.BIND_MESSAGE_INNER_QUEUE:
                sessions.kick(JSONUtils.fromJson(message.getBody(), Session.class));
                break;
            case Constants.PUSH_MESSAGE_INNER_QUEUE:
                pusher = JSONUtils.fromJson(message.getBody(), new TypeReference<Pusher<xin.alum.aim.model.Message>>() {
                });
                groups.get(pusher.getRecipient()).sends(pusher.getData());
                break;
            case Constants.REPLY_MESSAGE_INNER_QUEUE:
                if (AIM.message != null) {
                    AIM.message.onMessage(message.getBody());
                } else {
                    pusher = JSONUtils.fromJson(message.getBody(), new TypeReference<Pusher<Reply>>() {
                    });
                    if (pusher.getRecipient() == null || pusher.getRecipient().isEmpty() || pusher.getRecipient() == Sessions.ALL_SESSIONS) {
                        sessions.sends(pusher.getData());
                    } else {
                        groups.get(pusher.getRecipient()).sends(pusher.getData());
                    }
                }
                break;
            default:
        }
    }
}
